import { CropperType, ImgToolsType } from "@/components/imgTools/types/type";
import { Ref, ref, watchEffect } from "vue";

/**
 * 图片拖拽方法
 * @param toolOptions 初始配置对象
 * @param cropperStyle 裁剪数据对象
 * @param width canvas宽度
 * @param height canvas高度
 * @param imgWidth 图片宽度
 * @param imgHeight 图片高度
 * @param setCutPart 图片裁剪方法
 * @returns
 */
export const useImgMove = (
    toolOptions: ImgToolsType,
    cropperStyle: CropperType,
    width: Ref<number>,
    height: Ref<number>,
    imgWidth: Ref<number>,
    imgHeight: Ref<number>,
    setCutPart:Function
) => {
    const isMove = ref(false)
    const cursorStyle = ref('default')
    const left = ref(0)
    const top = ref(0)

    watchEffect(() => {
        left.value = cropperStyle.imgLeft
        top.value = cropperStyle.imgTop
    })

    // 计算裁剪框的坐标,canvas中心点为原点
    const getCropperPosition = (type:string) => {
        let x = 0
        let y = 0
        switch(type){
            case "topLeft":
                x = cropperStyle.left - imgWidth.value / 2
                y = cropperStyle.top - imgHeight.value / 2
                break;
            case "topRight":
                x = cropperStyle.width + cropperStyle.left - imgWidth.value / 2
                y = cropperStyle.top - imgHeight.value / 2
                break;
            case "bottomLeft":
                x = cropperStyle.left - imgWidth.value / 2
                y = cropperStyle.height + cropperStyle.top - imgHeight.value / 2
                break;
            case "bottomRight":
                x = cropperStyle.width + cropperStyle.left - imgWidth.value / 2
                y = cropperStyle.height + cropperStyle.top - imgHeight.value / 2
                break;
        }
        return getRelativePosition(x,y)
    }

    // 计算旋转前的坐标(原点为canvas中心)
    const getRelativePosition = (x: number, y: number) => {
        const cosTheta = Math.cos(cropperStyle.rotate);
        const sinTheta = Math.sin(cropperStyle.rotate);
        // 逆旋转公式
        const x_relative = x * cosTheta + y * sinTheta;
        const y_relative = -x * sinTheta + y * cosTheta;

        return {
            x: x_relative,
            y: y_relative,
        }
    }

    // 判断坐标是否位于图片内
    const isInPicture = (x:number,y:number) => {
        const minX = -left.value
        const minY = -top.value
        const maxX = cropperStyle.bigWidth - left.value
        const maxY = cropperStyle.bigHeight - top.value
        if (x >= minX && x <= maxX && y <= maxY && y >= minY) return true
        return false
    }

    // 鼠标移动事件
    const canvasMouseMove = (e: MouseEvent) => {
        // 获取鼠标坐标
        const x0 = e.offsetX - width.value / 2
        const y0 = e.offsetY - height.value / 2
        // 获取旋转前的坐标
        const { x, y } = getRelativePosition(x0, y0)
        isMove.value = true
        if (isInPicture(x,y)){
            isMove.value = true
            cursorStyle.value = 'grab'
        }else{
            isMove.value = false
            cursorStyle.value = 'default'
        }
    }

    // 判断拖拽后裁剪框四个顶点是否位于图片内
    const isCutInPicture = () => {
        const topLeft = getCropperPosition("topLeft")
        const topRight = getCropperPosition("topRight")
        const bottomLeft = getCropperPosition("bottomLeft")
        const bottomRight = getCropperPosition("bottomRight")
        return isInPicture(topLeft.x, topLeft.y) && isInPicture(topRight.x, topRight.y) && isInPicture(bottomLeft.x, bottomLeft.y) && isInPicture(bottomRight.x, bottomRight.y)
    }

    // 拖拽图片
    const canvasMouseDown = (e: MouseEvent) => {
        if(!isMove.value) return
        e.preventDefault()
        cursorStyle.value = 'grabbing'
        changeOpacity(1,0.4)
        let x = e.clientX
        let y = e.clientY
        let left0 = 0
        let top0 = 0
        document.onmousemove = (elMove:MouseEvent) => {
            let moveX = elMove.clientX - x
            let moveY = elMove.clientY - y
            x = elMove.clientX
            y = elMove.clientY
            left0 = left.value
            top0 = top.value
            // 判断移动后裁剪框是否位于图片内，位于图片内，可以进行拖拽
            left.value = left.value - moveX
            top.value = top.value - moveY
            if (isCutInPicture()){
                // 记录图片当前的位置
                cropperStyle.imgLeft = left.value
                cropperStyle.imgTop = top.value
                // 重新绘制
                setCutPart()
            }else{
                // 如果不位于图片内，不进行操作
                left.value = left0
                top.value = top0
            }
        }
        document.onmouseup = () => {
            document.onmousemove = null
            document.onmouseup = null
            cursorStyle.value = 'grab'
            changeOpacity(0,0.8)
        }
    }
    // 改变透明度并重新绘制
    const changeOpacity = (lineOpacity:number,imgOpacity:number) => {
        cropperStyle.cutLineOpacity = lineOpacity,
        toolOptions.opacity = imgOpacity
        setCutPart()
    }

    return {
        canvasMouseMove,
        canvasMouseDown,
        isMove,
        cursorStyle
    }
}